﻿namespace EFS.RC.CC.Tools.Control
{
	/// <summary>
	/// Command decomission
	/// </summary>
	internal class Command : EFS.Common.Async.AsyncRoot
	{
		#region Composition

		// sync access
		private object syncAccess = new object();

		// command text
		private System.String text;

		// remote app
		EFS.RC.CC.Applications.Remote.Messaging remoteMessagingApplication = null;

		/// <summary>
		/// Status
		/// </summary>
		public enum CommandStatus { Idle, Executed }

		// Status
		private CommandStatus status = CommandStatus.Idle;

		#endregion

		#region Constructor
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="conversation"></param>
		/// <param name="remoteEndpoint"></param>
		public Command(System.String text, EFS.RC.CC.Applications.Remote.Messaging remoteMessagingApplication)
		{
			// check
			EFS.Common.Verify.Reference(remoteMessagingApplication, "remoteMessagingApplication");

			// set
			this.remoteMessagingApplication = remoteMessagingApplication;
			this.text = text;

			// log
			EFS.EventLog.Log.LogInfo("Command", this);
		}

		#endregion

		#region Usage

		/// <summary>
		/// Describe this object into a nice formated string
		/// </summary>
		/// <returns></returns>
		public override System.String Describe()
		{
			return System.String.Format("EFS.RC.CC.Tools.Control.Command for [{0}]", text);
		}

		/// <summary>
		/// Execute
		/// </summary>
		public EFS.Common.Async.AsyncProcess Execute()
		{
			// log
			EFS.EventLog.Log.LogInfo("Execute", this);

			// start
			return BeginAsyncProcess2(ExecuteCommand, OnExecuteCommandComplete);
		}

		#endregion

		#region Runtime

		/// <summary>
		/// Unhandled exception
		/// </summary>
		/// <param name="ex"></param>
		protected override void OnException(System.Exception ex)
		{
			// check
			EFS.Common.Verify.Reference(ex, "ex");

			// log
			EFS.EventLog.Log.LogException(ex, this);
		}

		#endregion

		#region Execute

		/// <summary>
		/// ExecuteCommand
		/// </summary>
		private void ExecuteCommand()
		{
			// log
			EFS.EventLog.Log.LogInfo("ExecuteCommand", this);

			// sync access
			// ~ commented for performance ~  EFS.EventLog.Log.LogExtended("Entering lock", new System.Diagnostics.StackTrace());
			lock (syncAccess)
			{
				if (status != CommandStatus.Idle)
				{
					throw new System.InvalidOperationException("Only Idle Command can be started");
				}

				// started
				status = CommandStatus.Executed;
			}

			// delete
			switch (text)
			{
				case "reset reload":
					{
						EFS.RC.CC.Platform.Instance.EndPointRegistrar.OficeServicePresencesRegistrar.OperatorOfficeServiceEndPointPresence.PresenceEndPointApplication.ResetReloadTime();
						remoteMessagingApplication.BeginDataSend("Deployment Reload has been reset.");
						break;
					}
				case "reset config":
					{
						try
						{
							// reload
							EFS.RC.CC.Config.Settings.Reload();

							// ok
							remoteMessagingApplication.BeginDataSend("Config reloaded.");
						}
						catch (System.Exception ex)
						{
							// log
							EFS.EventLog.Log.LogException(ex, null);

							// error
							remoteMessagingApplication.BeginDataSend(ex.Message);
						}

						break;
					}
				case "show config":
					{
						// get description
						remoteMessagingApplication.BeginDataSend(EFS.RC.CC.Config.Settings.Describe());
						break;
					}
				case "show status":
					{
						remoteMessagingApplication.BeginDataSend(EFS.RC.CC.Platform.Instance.EndPointRegistrar.OficeServicePresencesRegistrar.OperatorOfficeServiceEndPointPresence.PresenceEndPointApplication.StatusDescription());
						break;
					}
				case "sal on":
					{
						// on
						EFS.RC.CC.SAL.Config.Settings.Enabled = true;

						// ok
						remoteMessagingApplication.BeginDataSend("SAL Enabled.");
						break;
					}
				case "sal off":
					{
						// off
						EFS.RC.CC.SAL.Config.Settings.Enabled = false;

						// ok
						remoteMessagingApplication.BeginDataSend("SAL Disabled.");
						break;
					}
				case "tell me all":
					{
						EFS.RC.CC.SAL.Loggers.Logger.Instance.AddWriter<EFS.RC.CC.Applications.Remote.Messaging>(remoteMessagingApplication);
						break;
					}
				case "handler":
					{
						remoteMessagingApplication.BeginDataSend(EFS.RC.CC.Config.Scheduler.Settings.Current.Describe());
						break;
					}
				case "help":
					{
						// make help
						System.Text.StringBuilder sb = new System.Text.StringBuilder();
						sb.AppendLine("~reset reload~ : Reset reload time for deployment;");
						sb.AppendLine("~reset config~ : Reset configuration will reload configuration from file");
						sb.AppendLine("~show config~ : Show currently used configuration");
						sb.AppendLine("~show status~ : Show current status for deployment");
						sb.AppendLine("~handler~ : Get current handler for incomming calls");
						sb.AppendLine("~sal on~ : Enbale SAL logger");
						sb.AppendLine("~sal off~ : Disable SAL logger");
						sb.AppendLine("~tell me all~ : Get SAL log into IM");
						sb.AppendLine("~help~ : Show this help");

						// send
						remoteMessagingApplication.BeginDataSend(sb.ToString());
						break;
					}
				default:
					{
						// send
						remoteMessagingApplication.BeginDataSend("Don't know what to do.");
						break;
					}
			}
		}

		/// <summary>
		/// ExecuteCommand complete
		/// </summary>
		/// <param name="ar"></param>
		private void OnExecuteCommandComplete(EFS.Common.Async.AsyncProcess ap)
		{
			// log
			EFS.EventLog.Log.LogInfo("OnExecuteCommandComplete", this);

			try
			{
				// check
				ap.Throw();

				// log
				EFS.EventLog.Log.LogInfo("OnExecuteCommandComplete SUCCCESS", this);
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		#endregion
	}
}
